package com.miaopasi.learn.springcloud.alibaba.sentinel.controller;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.log.StaticLog;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.miaopasi.learn.springcloud.common.pojo.CommonResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

/**
 * 测试类
 *
 * @author lixin
 */
@RestController
public class TestController {

    @GetMapping("/get/uuid")
    public String uuid() {
        return UUID.randomUUID().toString();
    }

    @GetMapping("/get/date")
    public String date() {
        ThreadUtil.sleep(1000);
        StaticLog.info("date...");
        return LocalDateTimeUtil.now().toString();
    }

    @GetMapping("/get/ex")
    public Integer ex() {
        int randomNumber = RandomUtil.randomInt(0, 5);
        StaticLog.info("randomNumber=" + randomNumber);
        return 10 / randomNumber;
    }

    @GetMapping("/get/news")
    @SentinelResource(value = "getNews", blockHandler = "dealGetNews")
    public String news(@RequestParam(name = "key") String key) {
        StaticLog.info("key=" + key);
        return key;
    }

    public String dealGetNews(String key, BlockException exception) {
        exception.printStackTrace();
        return "热点key限流处理" + key;
    }

    @GetMapping("/get/msg")
    @SentinelResource(value = "getMsg", blockHandler = "handleFailGetMsg")
    public CommonResult<String> msg(@RequestParam(name = "key") String key) {
        StaticLog.info("getMsg:key=" + key);
        return CommonResult.ok(key);
    }

    public CommonResult<String> handleFailGetMsg(String key, BlockException exception) {
        return CommonResult.fail(444L, "触发sentinel限流：" + exception.getRuleLimitApp());
    }

    @GetMapping("/get/handle")
    @SentinelResource(value = "handleBlock", blockHandlerClass = CustomBlockHandler.class, blockHandler = "handler01")
    public CommonResult<String> handleBlock() {
        StaticLog.info("==自定义处理限流逻辑调用==");
        return CommonResult.ok(null);
    }

    @GetMapping("/get/fallback")
    @SentinelResource(value = "fallback", fallback = "handleFallback", blockHandler = "blockHandler")
    public CommonResult<String> fallback(@RequestParam(name = "id") Integer id) {
        StaticLog.info("==自定义处理 限流+降级 逻辑调用==");
        if (id == 1) {
            throw new RuntimeException("请求ID不合法");
        }
        return CommonResult.ok(null);
    }

    /*** 发生异常处理方法 */
    public static CommonResult<String> handleFallback(Integer id, Throwable e) {
        return CommonResult.fail(445L, "触发sentinel自定义降级handleFallback：" + e.getMessage());
    }

    /*** 发生限流处理方法，blockHandler优先级大于fallback */
    public static CommonResult<String> blockHandler(Integer id, BlockException e) {
        return CommonResult.fail(446L, "触发sentinel自定义限流blockHandler：" + e.getRuleLimitApp());
    }

}
